from ..bot_plugin import Bot_plugin
from ..authorize_plugin.authorize_plugin import Plugin_authorize
from ..authorize_plugin.authorize_plugin import Plugin_suffix_manager
from ..authorize_plugin.authorize_plugin import Group_manager
from cqhttp import CQHttp
from bot_body import Bot_body
import logging
import colorful
import time

def resolve_snap_cmd(cmd:str):
    area=r"(?P<area>电信|电二|联通|网通|)"
    # qq=r"(?P<qq>\d{5,10}|\[CQ:at,qq=\d{5,10}\])"
    qq = r"((?P<qq>\d{5,10})|\[CQ:at,qq=(?P<qq_at>\d{5,10})\])"
    nickname = r"(?P<nickname_with_brace>[\(（].+[）\)])"
    alter = r"(?P<alter>.*)"
    conds=[]
    conds.append("(?P<special_cmd>本周活动|截图商城.*)")
    conds.append("(?P<head>截图)"+area+"(?P<alter>魅力红人|等级红人|荣誉红人|车神红人|宠物战力|珍宝红人|多宠天梯|幸运红人|跨服幸运赛|大宝达人|二宝达人|拉力总RL|拉力红人|辉煌总积分|辉煌之路|星光红人|车队荣誉|赛季战勋|竞技红人|冠军红人|成就红人|回馈红人|火线红人|淘汰赛红人|车队总荣誉|战勋红人|进阶改装|后花园红人|钻皇红人|皇族红人|情侣贵族|车队贵族|红包达人|人气红人|火力红人|宝石红人|恩爱红人|情侣红人|名师红人|舞蹈红人|改装红人|养鱼红人|鲜花红人|酷币红人|日魅力红人|日火力红人|日赠送红人|周魅力红人|月魅力红人|日喇叭红人|周喇叭红人|日表白红人|周表白红人|日祝福红人|周祝福红人)")
    conds.append("(?P<head>截图|查询)"+area+nickname+alter)
    conds.append("(?P<head>截图|查询)"+area+qq+alter)
    conds.append("(?P<head>截图|查询)"+area+alter)
    # conds.append("(?P<special_cmd>本周活动)")

    import re
    for i,cond in enumerate(conds):
        ret =re.match(cond,cmd)
        if ret == None:
            continue
        flag=True
        res = ret.groupdict()
        if 'area' in res and res['area'] == '':
            res['area'] = "电信"
        if 'qq' in res and res['qq'] == None:
            res['qq'] = res['qq_at']
        if i == 0:
            ans = res['special_cmd']
        elif i == 1:
            ans = res['head'] + res['area'] + res['alter']
        elif i == 2:
            ans = res['head'] + res['area'] + res['nickname_with_brace'] + res['alter']
        elif i == 3:
            ans = res['head'] + res['area'] + res['qq'] + res['alter']
        elif i == 4:
            ans = res['head'] + res['area'] + "{asker_qq}" + res['alter']
        res['ans'] = ans.replace(' ','')
        return res
    return None

class Plugin_snap(Bot_plugin):
    def __init__(self, bot_body: Bot_body, authorizer: Plugin_authorize, suffix_manager: Plugin_suffix_manager, name="snapshot for qqspeed"):
        Bot_plugin.__init__(self, bot_body, name=name)
        ret = self.bot.can_send_image()
        self.can_send_image = ret['yes']
        # ret = self.bot.can_send_record()
        # self.can_send_record = ret['yes']
        ret = self.bot.get_login_info()
        self.user_id = ret['user_id']
        # self.nickname = ret['nickname']
        logging.debug(colorful.cyan("can_send_image={}".format(
            self.can_send_image
        )))
        self.authorizer = authorizer
        self.suffix_manager = suffix_manager
        self.forward_client=''
        # self.forward_client='snap_client'

        self.help_msg=r"""【截图帮助】
0. 截图帮助：显示本条信息
1. 截图：截图本人电信区资料
2. 截图联通：截图本人联通区资料
3. 截图车队：截图本人车队资料
4. 截图[QQ]：截图对应QQ的资料
5. 截图[@某人]：截图被at群员的资料
6. 本周活动：显示本周活动
7. 截图商城：截图商城道具
8. 截图魅力红人：截图红人馆
9. 授权帮助：查看授权指令
10. 后缀帮助：查看后缀指令
"""
        self.global_help_msg = "{}\n{}\n{}".format(self.help_msg, self.authorizer.help_msg, self.suffix_manager.help_msg)

        # configs
        self.reset_interval = 3600
        self.mid_group=769736468
        self.initial_timeout = 3 # snap 3 times for 1 cmd
        self.check_order_done_time_s = 15 # check every 15 seconds
        self.max_g_error_cnt = 4 # accept most 4 cmds failed
        # for one group, user can order snap up to 5 times in 15 seconds
        self.max_last_cnt = 5 
        self.min_last_interval = 15
        self.server_qqs = dict()
        self.server_qqs['index'] = 0
        self.server_qqs['value'] = [3376871195, 354713628, 3339784028]
        # self.server_qqs['value'] = [354713628, 3339784028]
        assert(len(self.server_qqs['value'])>0)

        self.reset()

    def reset(self):
        self.g_error_cnt = 0
        self.last_queries_time = dict()
        self.orders = dict()
        self.order_cnt = 0
        self.failed_orders = set()
    def reset_server(self, reset_msg=""):
        if reset_msg == "":
            reset_msg = r"""fromGroup:{fromGroup}
fromQQ:{fromQQ}
order:{order}
operateQQ:0
clientQQ:{self_qq}""".format(
                fromGroup=self.mid_group,
                fromQQ=self.report_qq,
                order='重启机器人',
                self_qq=self.user_id
            )
        self.bot.send_group_msg(group_id=self.mid_group, message=reset_msg)

    def automatically_reset(self):
        time.sleep(self.reset_interval)
        if self.g_error_cnt >= self.max_g_error_cnt:
            self.reset()
            self.reset_server()


    def get_next_server_qq(self):
        '''
        return next server qq
        '''
        index = self.server_qqs['index']
        value = self.server_qqs['value'][index]
        next_index = (index+1) % len(self.server_qqs['value'])
        self.server_qqs['index'] = next_index
        return value

    def check_order_done(self, order_id:int):
        time.sleep(self.check_order_done_time_s)
        if order_id not in self.orders: # 对应的命令已经有了回复
            return
        order = self.orders[order_id]
        order['timeout'] -= 1
        if order['timeout'] > 0:
            self.jietu_by_order_id(order_id)
        else:
            self.failed_orders.add(order_id)
            reply_msg = "[CQ:at,qq={}]截图失败，请重试！".format(order['user_id'])
            self.bot.send_group_msg(group_id=order['group_id'], message=reply_msg)
            self.g_error_cnt+=1
            if (self.g_error_cnt >= self.max_g_error_cnt):
                report_msg = "[CQ:at,qq={}]命令失败次数已达到{}次，暂停截图，将在{}秒后自动重启，也可以手动输入指令【重启机器人】重启！".format(
                    self.report_qq, self.g_error_cnt, self.reset_interval)
                self.bot.send_group_msg(group_id=self.mid_group, message=report_msg)
                import threading
                thread = threading.Thread(target=self.automatically_reset)
                thread.setDaemon(True)
                thread.start()
        
    def jietu_by_order_id(self, order_id):
        if order_id not in self.orders:
            return -1
        order = self.orders[order_id]
        if (self.g_error_cnt >= self.max_g_error_cnt):
            reply_msg = "[CQ:at,qq={}]机器人重启中，请稍后再试！".format(order['user_id'])
            self.bot.send_group_msg(group_id=order['group_id'], message=reply_msg)
            return -1
        if order['timeout'] <= 0:
            reply_msg = "[CQ:at,qq={}]截图失败，请重试！".format(order['user_id'])
            self.bot.send_group_msg(group_id=order['group_id'], message=reply_msg)
            return -1
        server_qq = self.get_next_server_qq()
        order_msg = r"""fromGroup:{group_id}
fromQQ:{user_id}
order:{cmd}
operateQQ:{server_qq}
clientQQ:{self_qq}
orderId:{order_id}""".format(
    group_id=order['group_id'],
    user_id = order['user_id'],
    cmd = order['cmd'],
    server_qq = server_qq,
    self_qq = self.user_id,
    order_id = order['order_id']
)
        # self.bot.send_group_msg(group_id=order['group_id'], message=order_msg)
        self.bot.send_group_msg(group_id=self.mid_group, message=order_msg)

        import threading
        thread = threading.Thread(target=self.check_order_done, args=(order_id,))
        thread.setDaemon(True)
        thread.start()
        # self.bot.send_group_msg(group_id=self.mid_group, order_msg)

    def resolve_msg_to_dict(self, msg):
        try:
            msg = msg.strip().split('\n')
            ans = dict()
            for line in msg:
                p = line.find(':')
                if p == -1:
                    return dict()
                key = line[:p].strip()
                value = line[p+1:].strip()
                ans[key] = value
            return ans
        except:
            import traceback
            traceback.print_exc()
            return dict()
        

    def snap_it(self, group_id:int, user_id:int, cmd:str, order_id:int, timeout:int):
        if group_id not in self.last_queries_time:
            v = dict()
            v['index'] = 0
            v['value'] = [0 for i in range(self.max_last_cnt)]
            v['value'][0] = time.time()
            self.last_queries_time[group_id] = v
        else:
            v = self.last_queries_time[group_id]
            last_index = (v['index'] + 1 ) % self.max_last_cnt
            last_time = v['value'][last_index]
            now_time = time.time()
            diff_time = now_time - last_time
            if diff_time > self.min_last_interval:
                v['value'][last_index] = now_time
                v['index'] = last_index
            else: # 不能截图
                remaining_time = self.min_last_interval - diff_time
                reply_msg = "[CQ:at,qq={}]距离下次截图还剩{}秒！".format(user_id, int(remaining_time))
                self.bot.send_group_msg(group_id=group_id, message=reply_msg)
                return 0
        if timeout<=0: # cmd failed many times
            return -1
        order = dict()
        order['group_id'] = group_id
        order['user_id'] = user_id
        order['cmd'] = cmd
        order['order_id'] = order_id
        order['timeout'] = timeout
        self.orders[order_id] = order
        self.jietu_by_order_id(order_id)
        return 0


    def handle_msg(self, context):
        bot = self.bot
        if 'message_type' in context and context['message_type'] == 'group': # group chat
            
            if context['raw_message'] == '重启机器人' and context['user_id'] in self.master_qqs:
                reset_msg = r"""fromGroup:{fromGroup}
fromQQ:{fromQQ}
order:{order}
operateQQ:0
clientQQ:{self_qq}""".format(
                    fromGroup=context['group_id'],
                    fromQQ=context['sender']['user_id'],
                    order=context['raw_message'],
                    self_qq=self.user_id
                )
                self.reset()
                self.reset_server(reset_msg=reset_msg)
                bot.send(context, "本机重启已完成，并且服务器重启指令已发出！")
            if context['group_id'] == self.mid_group:
                #处理中间群的回复
                ret = self.resolve_msg_to_dict(context['raw_message'])
                if 'operateQQ' not in ret:
                    return
                operateQQ = int(ret['operateQQ'])
                if operateQQ != self.user_id and operateQQ != 0:
                    return

                if self.forward_client:
                    forward_dict = ret.copy()
                    forward_dict['operateQQ'] = self.forward_client
                    forward_msg = "\n".join(['{}:{}'.format(k,forward_dict[k]) for k in forward_dict])


                fromQQ = int(ret['fromQQ'])
                fromGroup = int(ret['fromGroup'])
                if 'backMsg' in ret:
                    msg = '[CQ:at,qq={}]{}'.format(fromQQ,ret['backMsg'])
                    bot.send_group_msg(group_id=fromGroup, message=msg)
                    if self.forward_client:
                        bot.send_group_msg(group_id=context['group_id'], msg=forward_msg)
                else:
                    logging.debug(colorful.yellow("msg={}".format(context['raw_message'])))
                    orderId = int(ret['orderId'])
                    if orderId not in self.orders:
                        return
                    self.orders.pop(orderId)
                    if orderId in self.failed_orders:
                        self.g_error_cnt-=1 #只是超时了
                        self.failed_orders.discard(orderId) 
                        return #因为之前发送过【截图失败】，所以就不发送了
                    suffix = self.suffix_manager.query_suffix(fromGroup)
                    if self.forward_client:
                        forward_msg = forward_msg+"\nsuffix:" + suffix.replace("\n",r"\n")
                        bot.send_group_msg(group_id=context['group_id'], message=forward_msg)
                    if self.can_send_image:
                        # cq_img = "[CQ:image,file={}]".format(ret['imgUrl'])
                        from tools.CQ_tools import img_url_to_CQCode
                        cq_img = img_url_to_CQCode(ret['imgUrl'])
                    else:
                        cq_img = " 点击链接查看截图：\n{}\n".format(ret['imgUrl'])
                    msg = "[CQ:at,qq={}]{}{}".format(fromQQ, cq_img, suffix)
                    bot.send_group_msg(group_id = fromGroup, message=msg)

            ret = resolve_snap_cmd(context['raw_message'])
            if ret != None: # snapshot command
                have_authorization = self.authorizer.query_have_authorization(context['group_id'])
                snap_end_time = self.authorizer.query_end_time(context['group_id'])
                secs_3_days = 3*24*3600
                if snap_end_time == None or snap_end_time < time.time() - secs_3_days:
                    pass
                elif snap_end_time < time.time():
                    try:
                        bot.send(context, "本群授权已过期，请续费")
                    except:
                        pass
                else:
                    if context['raw_message'][:4] == '截图帮助':
                        bot.send(context, self.help_msg)
                    else:
                        cmd = ret['ans'].format(asker_qq=context['sender']['user_id'])
                        order_id = self.order_cnt+1
                        self.order_cnt += 1
                        self.snap_it(group_id=context['group_id'], user_id = context['sender']['user_id'], cmd=cmd,
                            order_id = order_id, timeout = self.initial_timeout)
            
                

                
            
            
            
                
            


